/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cx1.service.impl;

import com.rits.cloning.Cloner;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang.StringUtils;
import org.cx1.model.Blog;
import org.cx1.model.FeaturedList;
import org.cx1.model.FeaturedWallpaper;
import org.cx1.model.Inquiry;
import org.cx1.model.Invite;
import org.cx1.model.Lead;
import org.cx1.model.Listing;
import org.cx1.model.Photo;
import org.cx1.model.ds.MockDS;
import org.cx1.model.ds.MockDSData;
import org.cx1.model.utils.EmailInvitee;
import org.cx1.model.utils.Invitee;
import org.cx1.model.utils.MobileInvitee;
import org.cx1.model.utils.ServiceResponse;
import org.cx1.model.utils.SystemProperties;
import org.cx1.service.api.IMockDSService;
import org.cx1.service.api.IPhotoService;
import org.space4j.CommandException;
import org.space4j.LoggerException;
import org.space4j.Space;
import org.space4j.Space4J;
import org.space4j.command.CreateMapCmd;
import org.space4j.command.PutCmd;
import org.space4j.command.RemoveCmd;
import org.space4j.implementation.SimpleSpace4J;

/**
 *
 * @author ECH
 */
public class MockDSService implements IMockDSService {

    private static Space4J space4j = null;
    private static Space space = null;
    private static Map<Integer, MockDSData> users = null;
    private static final int MAP_ID = SystemProperties.MOCKDS_MAP_ID;
    private static final String MAP_NAME = SystemProperties.MOCKDS_MAP_NAME;
    private static final String SPACE_NAME = SystemProperties.MOCKDS_SPACE_NAME;

    static {
        try {
            space4j = new SimpleSpace4J(SPACE_NAME);
            space4j.start();
            space = space4j.getSpace();

            /*
             * If this is the first time, create our map that will hold our
             * User objects. Space4J comes with many ready-to-use commands.
             * One of them is the CreateMapCmd, that will create our initial
             * empty map that to hold our objects.
             */
            if (!space.check(MAP_NAME)) {
                space4j.exec(new CreateMapCmd<Integer, MockDSData>(MAP_NAME));
            }

            /*
             * Save the map reference, so that we don't have to 
             * get it from the Space every time.
             */
            users = space.get(MAP_NAME);

            //CX: load latest ds
            MockDSService mockDSService = new MockDSService();
            mockDSService.loadDS(MAP_ID, MAP_NAME);

        } catch (Exception ex) {
            Logger.getLogger(MockDSService.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public ServiceResponse<Boolean> persistDS(int mapID, String mapName) {
        ServiceResponse<Boolean> response = new ServiceResponse<Boolean>();
        boolean success = false;
        try {
            MockDSData data = new MockDSData();
            Cloner cloner = new Cloner();

            //data.setListings(cloner.deepClone(MockDS.getListings()));
            //data.setPlaces(cloner.deepClone(MockDS.getPlaces()));
            //data.setAmenities(cloner.deepClone(MockDS.getAmenities()));
            //data.setUsers(cloner.deepClone(MockDS.getUsers()));
            //data.setPhotos(cloner.deepClone(MockDS.getPhotos()));
            //data.setCompanies(cloner.deepClone(MockDS.getCompanies()));
            //data.setContacts(cloner.deepClone(MockDS.getContacts()));
            //data.setInquiries(cloner.deepClone(MockDS.getInquiries()));
            //data.setLeads(cloner.deepClone(MockDS.getLeads()));
            //data.setInvites(cloner.deepClone(MockDS.getInvites()));
            //data.setInvitees(cloner.deepClone(MockDS.getInvitees()));
            //data.setEmailInvitees(cloner.deepClone(MockDS.getEmailInvitees()));
            //data.setMobileInvitees(cloner.deepClone(MockDS.getMobileInvitees()));
            //data.setBlogs(cloner.deepClone(MockDS.getBlogs()));

            data.setFeaturedList((cloner.deepClone(MockDS.getFeaturedList())));
            data.setFeaturedWallpaper((cloner.deepClone(MockDS.getFeaturedWallpaper())));
            
            space4j.exec(new RemoveCmd(mapName, mapID));
            space4j.exec(new PutCmd(mapName, mapID, data));
            space4j.executeSnapshot();

            response.setResponse(success);
            response.setSuccessful(true);
        } catch (Exception ex) {
            response.setResponse(null);
            response.setSuccessful(false);
            response.setMessage(ex.getMessage());
            response.setException(ex);
            ex.printStackTrace();
        }
        return response;
    }

    @Override
    public ServiceResponse<Boolean> loadDS(int mapID, String mapName) {
        ServiceResponse<Boolean> response = new ServiceResponse<Boolean>();
        boolean success = false;
        try {
            Iterator<MockDSData> iter = space.getIterator(mapName);
            MockDSData data = null;
            if (iter != null) {
                while (iter.hasNext()) {
                    data = iter.next();
                    break;
                }
            }

            Cloner cloner = new Cloner();

            //MockDS.setListings(cloner.deepClone(data.getListings()));
            //MockDS.setPlaces(cloner.deepClone(data.getPlaces()));
            //MockDS.setAmenities(cloner.deepClone(data.getAmenities()));
            //MockDS.setUsers(cloner.deepClone(data.getUsers()));
            //MockDS.setPhotos(cloner.deepClone(data.getPhotos()));
            //MockDS.setCompanies(cloner.deepClone(data.getCompanies()));
            //MockDS.setContacts(cloner.deepClone(data.getContacts()));
            //MockDS.setInquiries(data.getInquiries() == null ? new ArrayList<Inquiry>() : cloner.deepClone(data.getInquiries()));
            //MockDS.setLeads(data.getLeads() == null ? new ArrayList<Lead>() : cloner.deepClone(data.getLeads()));
            //MockDS.setInvites(data.getInvites() == null ? new ArrayList<Invite>() : cloner.deepClone(data.getInvites()));
            //MockDS.setInvitees(data.getInvitees() == null ? new ArrayList<Invitee>() : cloner.deepClone(data.getInvitees()));
            //MockDS.setEmailInvitees(data.getEmailInvitees() == null ? new HashSet<EmailInvitee>() : cloner.deepClone(data.getEmailInvitees()));
            //MockDS.setMobileInvitees(data.getMobileInvitees() == null ? new HashSet<MobileInvitee>() : cloner.deepClone(data.getMobileInvitees()));
            //MockDS.setBlogs(data.getBlogs() == null ? new ArrayList<Blog>() : cloner.deepClone(data.getBlogs()));

            MockDS.setFeaturedList(data.getFeaturedList() == null ? new ArrayList<FeaturedList>() : cloner.deepClone(data.getFeaturedList()));
            MockDS.setFeaturedWallpaper(data.getFeaturedWallpaper()== null ? new ArrayList<FeaturedWallpaper>() : cloner.deepClone(data.getFeaturedWallpaper()));
            
            response.setResponse(success);
            response.setSuccessful(true);
        } 
        catch (Exception ex) {
            response.setResponse(null);
            response.setSuccessful(false);
            response.setMessage(ex.getMessage());
            response.setException(ex);
            ex.printStackTrace();
        }
        return response;
    }

    @Override
    public ServiceResponse<Boolean> cleanUnusedPhotos() {
        ServiceResponse<Boolean> response = new ServiceResponse<Boolean>();
        boolean success = false;
        try {
            List<String> writtenPhotoFilenames = getWrittenPhotos();
            List<String> listingsPhotoFilenames = getListingsPhotoFilenames();
            List<String> unusedPhotoFilenames = new ArrayList<String>();

            for (String writtenPhotoFilename : writtenPhotoFilenames) {
                if (!listingsPhotoFilenames.contains(writtenPhotoFilename.trim())) {
                    unusedPhotoFilenames.add(writtenPhotoFilename);
                }
            }

            if (unusedPhotoFilenames.size() > 0) {
                for (String unusedPhotoFilename : unusedPhotoFilenames) {
                    //System.out.println("unusedPhotoFilename: " + unusedPhotoFilename);
                    File file1 = new File(SystemProperties.PHOTO_DIRECTORY + "/" + unusedPhotoFilename);
                    if (file1.delete()) {
                        System.out.println(file1.getName() + " is deleted!");
                    } 
                    else {
                        System.out.println("Delete operation is failed. " + file1.getName());
                    }
                    
                    File file2 = new File(SystemProperties.PHOTO_DIRECTORY + "/002-" + unusedPhotoFilename);
                    if (file2.delete()) {
                        System.out.println("002-" + file1.getName() + "002-" + " is deleted!");
                    } 
                    else {
                        System.out.println("Delete operation is failed. " + file1.getName());
                    }
                    
                    File file3 = new File(SystemProperties.PHOTO_DIRECTORY + "/001-" + unusedPhotoFilename);
                    if (file3.delete()) {
                        System.out.println("002-" + file1.getName() + " is deleted!");
                    } 
                    else {
                        System.out.println("Delete operation is failed. " + "001-" + file1.getName());
                    }
                }
            }
        } 
        catch (Exception ex) {
            response.setResponse(null);
            response.setSuccessful(false);
            response.setMessage(ex.getMessage());
            response.setException(ex);
            ex.printStackTrace();
        }
        return response;
    }

    public List<String> getWrittenPhotos() {
        List<String> photoFilenames = new ArrayList<String>();
        File folder = new File(SystemProperties.PHOTO_DIRECTORY);
        for (final File fileEntry : folder.listFiles()) {
            String filename = fileEntry.getName();
            if (!StringUtils.isEmpty(filename) && !filename.startsWith("001-") && !filename.startsWith("002-")) {
                photoFilenames.add(filename);                
            }
        }
        return photoFilenames;
    }

    public List<String> getListingsPhotoFilenames() {
        IPhotoService photoService = new MPhotoService();
        List<Listing> listings = MockDS.getListings();
        List<Photo> listingPhotos = new ArrayList<Photo>();
        List<String> listingPhotoFileNames = new ArrayList<String>();

        if (listings != null && listings.size() > 0) {
            for (Listing listing : listings) {
                if (listing.getPhotoIDs() != null) {

                    for (String photoID : listing.getPhotoIDs()) {
                        ServiceResponse<Photo> sr1 = photoService.read(photoID);
                        if (sr1.getResponse() != null) {
                            //listingPhotos.add(sr1.getResponse());
                            System.out.println("CX: " + sr1.getResponse().getFilename());
                            listingPhotoFileNames.add(sr1.getResponse().getFilename());
                        }
                    }
                }
            }
        }
        return listingPhotoFileNames;
    }
    
    public static void main(String[] argv) {
        MockDSService service = new MockDSService();
        //service.getWrittenPhotos();
        //service.getListingsPhotos();

        service.getListingsPhotoFilenames();
    }
}
